import React, { useState, useEffect, createContext } from 'react';
//@ts-ignore
import { AreaChartOutlined, FunctionOutlined, AlertOutlined, FundOutlined, FileOutlined, DatabaseOutlined, ApiOutlined, PlayCircleOutlined, PauseCircleOutlined } from '@ant-design/icons';
import { Layout, Menu, Button, Badge, Empty } from 'antd';
import SelectFile from './components/SelectFile';
import Router, { routes } from './router';
import { Link } from 'react-router-dom';
import { ipcRenderer } from 'electron';
import { OperationData, StatusArray, monitorOperation, BadgeNum, calculateBadgeNum, FileInfo, ProcessInfo } from './api';
import MessageDetail from './components/MessageDetail';
import './App.css';


// 创建消息列表的上下文
export const MessageListContext = createContext({
  messageList: [] as OperationData[],
  currentMessage: {} as OperationData,
  // @ts-ignore
  setCurrentMessage: (message: OperationData) => { },
  currentMessageStatus: [] as StatusArray[],
  // @ts-ignore
  setCurrentMessageStatus: (status: StatusArray[]) => { },
  messageStatusList: [] as StatusArray[],
});

const { Header, Content, Sider } = Layout;


const initialBadgeNum: BadgeNum = {
  trace: {
    normal: 0,
    warning: 0,
    danger: 0
  },
  messageBox: {
    normal: 0,
    warning: 0,
    danger: 0
  },
  heap: {
    normal: 0,
    warning: 0,
    danger: 0
  },
  file: {
    normal: 0,
    warning: 0,
    danger: 0
  },
  registry: {
    normal: 0,
    warning: 0,
    danger: 0
  },
  socket: {
    normal: 0,
    warning: 0,
    danger: 0
  }
}
const App: React.FC = () => {

  const [currentMessage, setCurrentMessage] = useState<OperationData>({} as OperationData);
  const [currentMessageStatus, setCurrentMessageStatus] = useState<StatusArray[]>([] as StatusArray[]);

  const [messageList, setMessageList] = useState<OperationData[]>([]); // 消息列表

  const [messageStatusList, setMessageStatusList] = useState<StatusArray[]>([]); // 消息状态列表
  const [badgeNum, setBadgeNum] = useState<BadgeNum>(JSON.parse(JSON.stringify(initialBadgeNum)));


  const [heapAllocArray, setHeapAllocArray] = useState<string[]>([]); // 堆申请数组
  const [heapFreeArray, setHeapFreeArray] = useState<string[]>([]); // 堆释放数组
  const [fileInfoArray, setFileInfoArray] = useState<FileInfo[]>([]); // 文件信息数组
  const [processInfo, setProcessInfo] = useState<ProcessInfo>({ processPathName: '', processID: 0, threadID: 0 }); // 进程信息
  const [folderArray, setFolderArray] = useState<string[]>([]); // 文件夹数组

  const [inputValue, setInputValue] = useState('');

  const [isTracking, setIsTracking] = useState(false);

  const handleInputChange = (value) => {
    setInputValue(value);
  }

  const initialData = () => {
    setHeapAllocArray([]);
    setHeapFreeArray([]);
    setFileInfoArray([]);
    setFolderArray([]);
    setMessageList([]);
    setCurrentMessage({} as OperationData);
    setMessageStatusList([]);
    setBadgeNum(JSON.parse(JSON.stringify(initialBadgeNum)));
  }

  const handleClick = () => {
    if (!isTracking) {
      // 替换为可执行文件的路径
      const executablePath = 'D:\\source\\c++\\RuanJianKeShe\\hust-detours\\hookDLLInject\\x64\\Release\\hookDLLInject.exe';

      console.log('inputValue:', inputValue);
      const parameters = [inputValue]; // 根据需要传递的参数

      // 发送消息给Electron主进程执行可执行文件
      ipcRenderer.send('execute-executable', { executablePath, parameters });

      setIsTracking(true);
    } else {
      const { processID } = processInfo;
      console.log('processID:', processID);
      setIsTracking(false);
      ipcRenderer.send('kill-process', { processID });
      //重置数据
      initialData();
    }

  }


  useEffect(() => {
    let heapAllocArr = heapAllocArray;
    let heapFreeArr = heapFreeArray;
    let fileInfoArr = fileInfoArray;
    let folderArr = folderArray;
    //@ts-ignore
    const handleData = (event, data: string) => {
      console.log('Received HTTPData:', data);
      // console.log('parseData:', JSON.parse(data))
      if (JSON.parse(data).type !== 'hook') {
        const { processID, threadID } = JSON.parse(data).args;
        const processPathName = JSON.parse(data).args.processPathName;
        setProcessInfo({ processPathName, processID, threadID });
      } else {
        setMessageList(prevMessageList => [...prevMessageList, JSON.parse(data)]);

        let props = {
          heapAllocArray: heapAllocArr,
          heapFreeArray: heapFreeArr,
          fileInfoArray: fileInfoArr,
          processPathName: processInfo.processPathName,
          folderArray: folderArr
        }
        let res = monitorOperation(JSON.parse(data), props);
        // console.log('res:', res);
        setMessageStatusList(prevMessageStatusList => [...prevMessageStatusList, res.statusArray]);
        setHeapAllocArray(res.heapAllocArray);
        setHeapFreeArray(res.heapFreeArray);
        setFileInfoArray(res.fileInfoArray);
        setFolderArray(res.folderArray);

        const type = JSON.parse(data).hook_type;
        let newBadgeNum = calculateBadgeNum(res.statusArray, type, badgeNum);
        setBadgeNum(newBadgeNum);

        // console.log('messageList:', messageList);
      }

    }

    ipcRenderer.on('http-data', handleData);
    //@ts-ignore
    ipcRenderer.on('process-exit', (event, data) => {
      console.log('Process exit:', data);
      setIsTracking(false);
      //重置数据
      initialData();
    })

    return () => {
      ipcRenderer.removeListener('http-data', handleData);
    }
    // eslint-disable-next-line
  }, [messageList])



  return (
    <Layout style={{ width: '100vw', height: '100%' }}>
      <Header style={{ display: 'flex', alignItems: 'center' }}>
        <div className="demo-logo" />
        <SelectFile onInputChange={handleInputChange}></SelectFile>
        <Button type="primary" onClick={handleClick} icon={isTracking ? <PauseCircleOutlined /> : <PlayCircleOutlined />}>{isTracking ? '停止追踪' : '开始追踪'}</Button>
      </Header>
      <Layout>
        <Sider width={230} style={{ height: '100%' }} className="site-layout-background">
          <Menu
            mode="inline"
            defaultSelectedKeys={['1']}
            defaultOpenKeys={['sub1']}
            style={{ height: '100%', borderRight: 0 }}
          >
            {
              routes.map((route, index) => {
                if (route.path !== '/') {
                  return (
                    <Menu.Item key={index} icon={route.icon} style={{height:'50px', borderBottom:'1px solid #e8e8e8'}} >
                      <Link to={route.path} state={messageList} style={{display:'flex'}}>
                        <span style={{height:'45px'}}>{route.name}</span>
                        <span style={{ height:'45px',marginLeft:'auto',marginRight:'10px',display:'flex',flexDirection:'column',justifyContent:'center'}}>
                          {
                            // @ts-ignore
                            badgeNum[route.type] && badgeNum[route.type].normal > 0 && <Badge count={badgeNum[route.type].normal} size='small' style={{ backgroundColor: 'rgb(45, 183, 245)' }}></Badge>
                          }
                          {
                            // @ts-ignore
                            badgeNum[route.type] && badgeNum[route.type].warning > 0 && <Badge count={badgeNum[route.type].warning} size='small' style={{ backgroundColor: 'orange' }}></Badge>
                          }
                          {
                            // @ts-ignore
                            badgeNum[route.type] && badgeNum[route.type].danger > 0 && <Badge count={badgeNum[route.type].danger} size='small' style={{ backgroundColor: 'red' }}></Badge>
                          }
                        </span>
                      </Link>
                    </Menu.Item>
                  )
                }
              })
            }
          </Menu>
        </Sider>
        <Layout style={{ padding: '0 24px 24px', height: '100%', display: 'flex', flexDirection: 'row' }}>
          <Content className='messageList' style={{ width: '60%', marginRight: '24px', border: '1px solid #e8e8e8', overflow: 'auto' }}>
            <MessageListContext.Provider value={{ messageList, currentMessage, setCurrentMessage,currentMessageStatus,setCurrentMessageStatus, messageStatusList }}>
              <Router></Router>
            </MessageListContext.Provider>
          </Content>
          <Content className='messageDetail' style={{ width: '40%', border: '1px solid #e8e8e8', overflow: 'auto' }}>
            {/* 右边消息详情 */}
            <div style={{ overflowY: 'auto', height: '100%',backgroundColor:'white' }}>
              {/* 消息详情内容 */}
              {
                !currentMessage.api_name && <Empty></Empty>
              }
              {
                currentMessage.api_name && <MessageDetail message={currentMessage} messageStatus={currentMessageStatus}></MessageDetail>
              }
            </div>
          </Content>
        </Layout>
      </Layout>
    </Layout>
  );
};

export default App;